/*
 * ClientServiceImpl.java
 *
 * Created on June 20, 2009, 5:38 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package fhv.itb.mst2955.server;

import fhv.itb.mst2955.server.persistence.Contact;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import fhv.itb.mst2955.client.ContactService;
import fhv.itb.mst2955.client.model.ContactProxy;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;


/**
 *
 * @author Malcolm
 */
public class ContactServiceImpl extends RemoteServiceServlet implements
        ContactService {

    @PersistenceContext(unitName = "AddressBookNBPU")
    private EntityManager em;
    @Resource
    private UserTransaction utx;


    public Vector<ContactProxy> getContacts() {
        Query q = em.createNamedQuery("Contact.findAll");
        List<Contact> contacts = q.getResultList();
        Vector<ContactProxy> cls = new Vector<ContactProxy>();

        for (Contact c : contacts) {
            ContactProxy contact = createContactProxyFromContact(c);
            cls.add(contact);
        }

        return cls;
    }


    public Integer deleteContact(int id) {
        try {
            utx.begin();
            em.joinTransaction();
            Contact c = em.find(Contact.class, id);
            if (c != null) {
//                em.merge(c);
                em.remove(c);
                utx.commit();
                return new Integer(1);
            }
        } catch (Exception ex) {
            Logger.getLogger(ContactServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
            try {
                utx.rollback();
            } catch (Exception ex1) {
                Logger.getLogger(ContactServiceImpl.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }

        return new Integer(0);
    }


    public void newContact(ContactProxy client) {
        try {
            utx.begin();
            em.joinTransaction();
            Contact c = createContactFromProxy(client);
            em.merge(c);
            em.persist(c);
        } catch (NotSupportedException ex) {
            Logger.getLogger(ContactServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(ContactServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public void putContacts(Vector<ContactProxy> contacts) {

        try {
            utx.begin();
            em.joinTransaction();

            for (ContactProxy cp : contacts) {
                Contact sc = em.find(Contact.class, cp.getId());

                try {
                    if (sc != null) {
                        if (cp.getVersionNr() > sc.getVersionNr()) {
                            sc = createContactFromProxy(cp);
                            em.merge(sc);
                        }
                    } else {
                        sc = createContactFromProxy(cp);
                        em.merge(sc);
                        em.persist(sc);
                    }

                } catch (NoResultException nre) {
                    // insert client-side client into server db
                    sc = createContactFromProxy(cp);
                    em.merge(sc);
                    em.persist(sc);
                }
            }

            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (IllegalStateException ex1) {
                Logger.getLogger(AddressServiceImpl.class.getName()).log(Level.SEVERE, null, ex1);
            } catch (SecurityException ex1) {
                Logger.getLogger(AddressServiceImpl.class.getName()).log(Level.SEVERE, null, ex1);
            } catch (SystemException ex1) {
                Logger.getLogger(AddressServiceImpl.class.getName()).log(Level.SEVERE, null, ex1);
            }
            Logger.getLogger(AddressServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        }

    }


    /**
     * Creates a server-side Contact from a client-side ContactProxy.
     *
     * @param c
     * The ContactProxy object to create a server-side Contact from.
     *
     * @return
     * A server-side Contact object.
     */
    public static Contact createContactFromProxy(ContactProxy contact) {
        Contact c = new Contact();
        c.setId(contact.getId());
        c.setAddressID(contact.getAddressID());
        c.setFirstName(contact.getFirstName());
        c.setLastName(contact.getLastName());
        c.setVersionNr(contact.getVersionNr());
        return c;
    }


    /**
     * Creates a client-side ContactProxy from a server-side Contact.
     *
     * @param c
     * The Contact object to create a client-side ContactProxy from.
     *
     * @return
     * A client-side ContactProxy object.
     */
    public static ContactProxy createContactProxyFromContact(Contact c) {
        ContactProxy contact = new ContactProxy();
        contact.setId(c.getId());
        contact.setAddressID(new Integer(c.getAddressID()));
        contact.setFirstName(c.getFirstName());
        contact.setLastName(c.getLastName());
        contact.setVersionNr(c.getVersionNr());
        return contact;
    }


    public void setUserTransaction(UserTransaction utx) {
        this.utx = utx;
    }


    public void setEntityManager(EntityManager em) {
        this.em = em;
    }

}
